package alipay

import (
	"fmt"
	alipay "github.com/smartwalle/alipay/v3"
	"log"
	"net/url"
	"pay/config"
	"strconv"
)

type AlipayConfig struct {
}
type Client struct {
	AlipayClient *alipay.Client
}

var MyClient Client

func (alipayConfig AlipayConfig) Init() {
	client, err1 := alipay.New(config.Config.AliPay.AppId, config.Config.AliPay.PrivateKey, true)
	if err1 != nil {
		fmt.Println("初始化支付宝失败, 错误信息为", err1)
	}
	// 加载证书
	if err := client.LoadAppCertPublicKeyFromFile(config.Config.AliPay.AppPublicCert); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}
	if err := client.LoadAliPayRootCertFromFile(config.Config.AliPay.AliPayPayRootCert); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}
	if err := client.LoadAlipayCertPublicKeyFromFile(config.Config.AliPay.AliPayPublicCert); err != nil {
		log.Println("加载证书发生错误", err)
		return
	}
	if err := client.SetEncryptKey(config.Config.AliPay.ApiKey); err != nil {
		log.Println("加载内容加密密钥发生错误", err)
		return
	}
	MyClient.AlipayClient = client
}

type NativePrePay struct {
	Description string `json:"description"`
	OutTradeNo  string `json:"outTradeNo"`
	NotifyUrl   string `json:"notifyUrl"`
	Total       int64  `json:"total"`
	TimeExpire  string `json:"timeExpire"`
	ReturnUrl   string `json:"return_url"`
}

func (nativePrePay NativePrePay) Native() (string, error) {
	var p = alipay.TradePagePay{}
	p.NotifyURL = nativePrePay.NotifyUrl
	p.TimeExpire = nativePrePay.TimeExpire
	p.Subject = nativePrePay.Description
	p.OutTradeNo = nativePrePay.OutTradeNo
	p.ProductCode = "FAST_INSTANT_TRADE_PAY"
	p.NotifyURL = config.Config.AliPay.CallbackUrl
	p.ReturnURL = nativePrePay.ReturnUrl
	callbackUrl := nativePrePay.NotifyUrl + "/alipay"
	encodedString := url.QueryEscape(callbackUrl)
	p.PassbackParams = encodedString
	num := float64(nativePrePay.Total) / 100.0
	str := strconv.FormatFloat(num, 'f', 2, 64)
	p.TotalAmount = str
	url, err := MyClient.AlipayClient.TradePagePay(p)
	// 处理错误
	if err != nil {
		// 处理错误
		log.Println("call Prepay err:%s", err)
		return "", err
	} else {
		// 处理返回结果
		return url.String(), nil
	}
}

func FindByOutTradeNo(outTradeNo string) (interface{}, error) {
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo
	res, err := MyClient.AlipayClient.TradeQuery(p)
	if err != nil {
		return "", err
	} else {
		return res, nil
	}
}
